package com.bstek.uflo.console.view.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.bstek.dorado.data.listener.GenericObjectListener;
import com.bstek.dorado.view.View;
import com.bstek.dorado.view.ViewElement;
import com.bstek.dorado.view.widget.grid.DataGrid;
import com.bstek.dorado.web.DoradoContext;
import com.bstek.uflo.console.view.security.filter.ElementFilter;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.process.node.Node;
import com.bstek.uflo.process.node.StartNode;
import com.bstek.uflo.process.node.TaskNode;
import com.bstek.uflo.process.security.ComponentAuthority;
import com.bstek.uflo.service.ProcessService;
import com.bstek.uflo.service.TaskService;

/**
 * @author Jacky.gao
 * @since 2013年10月21日
 */
public class FormGlobalComponentListener extends GenericObjectListener<View>
		implements ApplicationContextAware {
	
	private TaskService taskService;
	private ProcessService processService;
	private Collection<ElementFilter> filters;
	
	@Override
	public boolean beforeInit(View view) throws Exception {
		return true;
	}

	@Override
	public void onInit(View view) throws Exception {
		String taskId=DoradoContext.getCurrent().getRequest().getParameter("taskId");
		if(StringUtils.isEmpty(taskId))return;
		long id=0;
		try{
			id=Long.parseLong(taskId);
		}catch(Exception ex){
			return;
		}
		Task task=taskService.getTask(id);
		if(task==null)return;
		Node node=processService.getProcessById(task.getProcessId()).getNode(task.getNodeName());
		if(node instanceof TaskNode){
			TaskNode taskNode=(TaskNode)node;
			if(taskNode==null || taskNode.getComponentAuthorities()==null)return;			
			filterComponents(view.getInnerElements(), taskNode.getComponentAuthorities());
		}else if(node instanceof StartNode){
			StartNode startNode=(StartNode)node;
			if(startNode==null || startNode.getComponentAuthorities()==null)return;			
			filterComponents(view.getInnerElements(), startNode.getComponentAuthorities());
		}
	}

	private void filterComponents(Collection<ViewElement> elements,List<ComponentAuthority> componentAuthorities){
		if(elements==null || elements.size()==0)return;
		for(ViewElement element:elements){
			for(ElementFilter filter:filters){
				if(filter.support(element)){
					filter.filter(element, componentAuthorities);
					break;
				}
			}
			if(element instanceof DataGrid){
				DataGrid grid=(DataGrid)element;
				Collection<ViewElement> cols=new ArrayList<ViewElement>();
				cols.addAll(grid.getColumns());
				filterComponents(cols, componentAuthorities);								
			}else{
				filterComponents(element.getInnerElements(), componentAuthorities);				
			}
		}
	}
	
	public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
		filters=applicationContext.getBeansOfType(ElementFilter.class).values();
	}

	public ProcessService getProcessService() {
		return processService;
	}

	public void setProcessService(ProcessService processService) {
		this.processService = processService;
	}

	public TaskService getTaskService() {
		return taskService;
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}
}
